#include "doublelist.h"
#include "staffManage.h" 

#define DATABASE "staffmanage.db"

sqlite3 *db;

//负责人仓库
dlist_t doublelist_t;
int socket_TCP_ID;
struct sockaddr_in server_addr;


void do_client(int connectfd,MSG *msg);
void get_current_date(char date[]);

//初始化TCP
int init_TCP(const char ip[],const char port[])
{
	socklen_t socklen = sizeof(server_addr);	
	//TCP
	socket_TCP_ID = socket(PF_INET,SOCK_STREAM,0);
	if(socket_TCP_ID < 0)
	{
		perror("fail to socket");
		return -1;
	}
	//填充网络结构体
	bzero(&server_addr,sizeof(server_addr));
	server_addr.sin_family=PF_INET;
	server_addr.sin_addr.s_addr=inet_addr(ip);
	server_addr.sin_port=htons(atoi(port));
	if(bind(socket_TCP_ID,(struct sockaddr*)&server_addr,socklen) < 0)
	{
		perror("IP绑定失败！");
		return -1;
	}
		
	if(listen(socket_TCP_ID,100) < 0)
	{
		perror("fail to listen");
		return -1;
	}
	
	return 1;
}


//初始化管理员用户
void init_admin()
{
	char *errmsg;
	char **result;
	int line, column;
	if(sqlite3_get_table(db, "select * from staff where name='admin'", &result, &line, &column, &errmsg) != SQLITE_OK)
	{
		printf("%s\n",errmsg);
	}
	if(line > 0)
	{
		return;
	}else{
		printf("*************初始化管理员用户******************\n");
	}

	char sql1[200]="insert into staff(name,authority,gender,age,education,salary,password,check_in_time)values('admin',0,'m',1,'1',10000,'123456','2017-06-20 08:00:00')";
	char sql2[200]="insert into staff(name,authority,gender,age,education,salary,password,check_in_time)values('xiaoming',1,'m',1,'1',10000,'123456','2017-06-20 08:00:00')";
	if(sqlite3_exec(db, sql1, NULL, NULL, &errmsg) != SQLITE_OK)
	{
		printf("%s\n", errmsg);
	}
	if(sqlite3_exec(db, sql2, NULL, NULL, &errmsg) != SQLITE_OK)
	{
		printf("%s\n", errmsg);
	}
}

//注册
void do_register(int connectfd,MSG *msg)
{
	printf("do_register!!\n");
#if 1
	char date[32]={0};
	char *errmsg;
	get_current_date(date);
	struct staff mystaff = msg->nstaff;
    
	char sql1[512]={0};
	char sql2[512]="insert into staff(name,authority,gender,age,education,salary,password,check_in_time)values('%s' , %d , '%c' , %d , '%s' , %d ,'%s' , '%s' )";
	
	sprintf(sql1, sql2, mystaff.name, mystaff.authority, mystaff.gender , mystaff.age , mystaff.education
			,  mystaff.salary, mystaff.password , date);

	MSG rest={0};
	if(sqlite3_exec(db, sql1, NULL, NULL, &errmsg) != SQLITE_OK)
	{
		rest.type=-1;
		sqlite3_free(errmsg);
	}else{
	    rest.type=1;
	}

	printf("do_register!!3 %d\n",rest.type);

	send(connectfd, &rest, sizeof(MSG), 0);//发送给客户段，不管是成功还是失败

#endif
	return;
}
//登录
void do_login(int connectfd,MSG *msg)
{
	struct staff mystaff = msg->nstaff;
	char *errmsg;
	char **result;
	int line, column;
	int i,j;
	char sqlstr[128];

	printf("login id : %d,password:%s\n",mystaff.id,mystaff.password);

	sprintf(sqlstr, "select * from staff where id = '%d' and password ='%s'", mystaff.id, mystaff.password);
	
	printf("sql:%s",sqlstr);

	if(sqlite3_get_table(db, sqlstr, &result, &line, &column, &errmsg) != SQLITE_OK)
	{
		printf("%s\n",errmsg);
	}
	int is_manager=-1;
	int index = column;
	int current_login_id;
	for(i=0;i<line;i++)
	{
		is_manager=0;
		printf("第%d记录\n",i+1);
		for(j=0;j<column;j++)
		{
			if(strcmp(result[j],"authority")==0 && (strcmp(result[index],"0")==0) )
			{
				is_manager=1;
			}
			
			if(strcmp(result[j],"id")==0 )
			{
				current_login_id = atoi(result[index]);
			}
			index++;
		}
		putchar(10);
	}

	MSG remsg={0};
	remsg.send_id=current_login_id;

	if(is_manager==1){
		remsg.type=0;//管理员
		printf("管理员登录！！\n");
	}else if(is_manager==0){
		printf("普通用户登录！！\n");
		remsg.type=1;//普通用户
	}else{
		printf("登录失败！！\n");
		remsg.type=-1;//登录失败
	}

	send(connectfd, &remsg ,sizeof(MSG), 0);
	
	return;
}

int callback(void *arg, int f_num, char **f_value, char **f_name)
{
	int connectfd;
	MSG msg;
	connectfd = *(int *)arg;
	sprintf(msg.msg, "%s %s %s %s %s %s %s %s ", f_value[0], f_value[1],\
			f_value[2], f_value[3], f_value[4], f_value[5], f_value[6], f_value[7]);
	send(connectfd, &msg, sizeof(msg), 0); //send data to client
	return 0;
}


//查询单个员工
void select_sigle_staff(int connectfd,MSG *msg)
{
	char sqlstr[128], *errmsg;
	sprintf(sqlstr, "select * from staff where id = %d ", msg->id);
	if(sqlite3_exec(db, sqlstr, callback, (void *)&connectfd, &errmsg) != SQLITE_OK)
	{
		printf("erro: %s\n", errmsg);
		sqlite3_free(errmsg);
	}
	return;
}

void select_all_staff(int connectfd,MSG *msg)
{
	printf("select_all_staff()\n");
	//char sqlstr[128];
	char *errmsg;
	//int i;
	//for(i = 0; i < 10; i++)
	//{
		if(sqlite3_exec(db, "select * from staff", callback, (void *)&connectfd, &errmsg) != SQLITE_OK)
		{
			printf("erro: %s\n", errmsg);
			sqlite3_free(errmsg);
		}

	//}

	sleep(10);
	return;
}
#if 1
//查询全部员工
void select_all_staff1(int connectfd,MSG *msg)
{
	char *errmsg;
	char **result;
	int line, column;
	int i, j;
	char sqlstr[128]="select id,name,authority,gender,age,education,salary from staff";
	if(sqlite3_get_table(db, sqlstr, &result, &line, &column, &errmsg) != SQLITE_OK)
	{
		printf("%s\n",errmsg);
	}

	int index = column;
	//char *f_value[128]={0};
	MSG sdmsg={0};
	sdmsg.type=line;
	send(connectfd, &sdmsg, sizeof(MSG), 0); //send data to client

	for(i=0;i<line;i++)
	{

		for(j=0;j<column;j++)
		{

			if(strcmp(result[j],"id") ==0 )
			{
				sdmsg.nstaff.id=atoi(result[index]);
			}
			else if(strcmp(result[j],"name") ==0 )
			{
				strcpy(sdmsg.nstaff.name,result[index]);
			}
			else if(strcmp(result[j],"authority") ==0 )
			{
				sdmsg.nstaff.authority=atoi(result[index]);
			}
			else if(strcmp(result[j],"gender") ==0 )
			{
				sdmsg.nstaff.gender=result[index][0];
			}
			else if(strcmp(result[j],"age") ==0 )
			{
				sdmsg.nstaff.age=atoi(result[index]);
			}
			else if(strcmp(result[j],"education") ==0 )
			{
				strcpy(sdmsg.nstaff.education,result[index]);
			}
			else if(strcmp(result[j],"salary") ==0 )
			{
				sdmsg.nstaff.salary=atoi(result[index]);
			}

			//f_value[j]=result[index];
			index++;
		}
		putchar(10);

		sdmsg.type=line;
		
#if 0
		sprintf(sdmsg.msg, "%s %s %s %s %s %s %s", f_value[0], f_value[1],\
			f_value[2], f_value[3], f_value[4], f_value[5], f_value[6]);
#endif
		sprintf(sdmsg.msg, "%4d    %4s    %4d    %4c    %4d    %4s    %4d", sdmsg.nstaff.id, sdmsg.nstaff.name,\
			sdmsg.nstaff.authority,sdmsg.nstaff.gender, sdmsg.nstaff.age, sdmsg.nstaff.education,sdmsg.nstaff.salary);
	
		send(connectfd, &sdmsg, sizeof(MSG), 0); //send data to client

		putchar(10);
	}

}

#endif
//更新员工
void update_staff(int connectfd,MSG *msg)
{
	printf("update_staff()\n");
	char sqlstr[128], *errmsg;
	sprintf(sqlstr,"update staff set password = %s where id = %d",msg->msg,msg->id);
	printf("update_staff:sql:%s\n ",sqlstr);
	if(sqlite3_exec(db, sqlstr, callback, (void *)&connectfd, &errmsg) != SQLITE_OK)
	{
		printf("erro: %s\n", errmsg);
		sqlite3_free(errmsg);
	}
	
}

void update_root(int connectfd, MSG *msg)
{
	printf("update_root");
	char sqlstr[128], *errmsg;

	sprintf(sqlstr,"update staff set %s = '%s' where id = %d",msg->item,msg->msg, msg->id);
	
	printf("update_root:%s\n",sqlstr);

	if(sqlite3_exec(db, sqlstr, callback, (void *)&connectfd, &errmsg) != SQLITE_OK)	
	{
		printf("erro: %s\n", errmsg);
		sqlite3_free(errmsg);
	}
	return;
}


//删除员工
void delete_staff(int connectfd,MSG *msg)
{
	printf("delete_staff()\n");
	char sqlstr[128], *errmsg;
	sprintf(sqlstr, "delete  from staff 	where id = %d", msg->id);
	if(sqlite3_exec(db, sqlstr, callback, (void *)&connectfd, &errmsg) != SQLITE_OK)
	{
		printf("erro: %s\n", errmsg);
		sqlite3_free(errmsg);
	}
	return;
}

//员工打卡
void check_work_time_staff(int connectfd,MSG *msg) 
{

}
//接收客户端发送的消息
void receive_client_msg(int connectfd,MSG *msg)
{
	char *errmsg;
	char sqlstr[300]="insert into message(send_id,receive_id,msg,send_time,read_time,is_read)\
					  values(%d,%d,'%s','%s','%s',%d)";
	char sql1[300]={0};	
	sprintf(sql1,sqlstr, msg->send_id,msg->receive_id,msg->msg,msg->send_time,"0000-00-00 00:00:00",0);

	if(sqlite3_exec(db, sql1, NULL, NULL, &errmsg) != SQLITE_OK)
	{
		printf("%s\n", errmsg);
	}
	
}
//发送消息到客户端
void send_client_msg(int connectfd,MSG *msg)
{
	char sqlstr[128];
	//拼接字符串
	sprintf(sqlstr, "select * from message where receive_id=%d and is_read=0", msg->receive_id);

	char *errmsg;
	char **result;
	int line, column;
	int i, j;
	if(sqlite3_get_table(db, sqlstr, &result, &line, &column, &errmsg) != SQLITE_OK)
	{
		printf("%s\n",errmsg);
	}

	int index = column;

	for(i=0;i<line;i++)
	{
		MSG smsg={0};
		for(j=0;j<column;j++)
		{   
			if(strcmp(result[j],"id")==0)
			{
				smsg.id=atoi(result[index]);
			}
			if(strcmp(result[j],"send_id")==0)
			{
				smsg.send_id=atoi(result[index]);
			}
			if(strcmp(result[j],"receive_id")==0)
			{
				smsg.receive_id=atoi(result[index]);
			}
			if(strcmp(result[j],"msg")==0)
			{
				strcpy(smsg.msg,result[index]);
			}
			if(strcmp(result[j],"send_time")==0)
			{
				strcpy(smsg.send_time,result[index]);
			}

			printf("key = %s,value=%s",result[j],result[index]);
			index++;
		}

		send(connectfd,&smsg, sizeof(MSG), 0);
		char updatesql[200]={0};
	
		sprintf(updatesql,"update message set is_read=1 where id=%d", smsg.id);

	
		if(sqlite3_exec(db, updatesql, NULL, NULL, &errmsg) != SQLITE_OK)
		{
			printf("%s\n", errmsg);
		}

		putchar(10);
	}

}

time_t StringToDatetime(char* cha)
{
	if(cha == NULL)
	{
		return (time_t)0;
	}
	
	struct tm tm_;
	int year,month,day,hour,minute,second;
	sscanf(cha,"%d-%d-%d %d:%d:%d",&year,&month,&day,&hour,&minute,&second);
	tm_.tm_year=year - 1900;
	printf("do_chat\n");
	tm_.tm_mon=month-1;
	tm_.tm_mday=day;
	tm_.tm_hour=hour;
	tm_.tm_min=minute;
	tm_.tm_sec=second;
	tm_.tm_isdst=0;
	time_t t_=mktime(&tm_);
	return t_;
}

void get_current_date(char date[])
{
	time_t t;
	struct tm *tp;
	time(&t);
	tp = localtime(&t);
	strftime(date, 32, "%Y-%m-%d %H:%M:%S", tp);
	return;
}


//负责人操作方法
void* manager_task(void *arg)
{
	TCP_MANAGER tcp_manager = *(TCP_MANAGER*)arg;
	int connectfd = tcp_manager.connectfd;
	//struct sockaddr_in client_addr=tcp_manager.client_addr;

	MSG msg;//携带操作类型的消息
	
	while(1)
	{
		ssize_t rest=recv(connectfd, &msg, sizeof(msg), 0);
		if(rest <= 0)
		{
			close(connectfd);
			pthread_exit(NULL);
			return NULL;
		}

		//printf("gogo msg.type=%d ,rest = %d \n",msg.type,rest);

		char now_date[32];
		get_current_date(now_date);
		//time_t now_time = StringToDatetime(now_date);
		//time_t connect_time_ = StringToDatetime(tcp_manager.connect_time);
	
		do_client(connectfd,&msg);		
		
#if 0
		if((now_time - connect_time_) > 20)
		{
			close(connectfd);
			delete_doublelist(doublelist_t,arg,sizeof(tcp_manager));
			return NULL;
		}
#endif
	}

	return NULL;
}

void do_client(int connectfd,MSG *msg)
{
	//printf("do_client msg type = %d\n",msg->type);
	switch(msg->type)
	{

	case R:
		do_register(connectfd, msg);
		break;
	case L:
		do_login(connectfd,msg);
		break;
	case Q:
		select_sigle_staff(connectfd,msg);
		break;
	case A:
		select_all_staff1(connectfd ,msg);
		break;
	case U:
		update_root(connectfd,msg);
		break;
	case UU:
		update_staff(connectfd,msg);
		break;
	case D:
		delete_staff(connectfd ,msg);
		break;
	case RC:
		receive_client_msg(connectfd,msg);
		break;
	case SC:
		send_client_msg(connectfd,msg);
		break;
	case C:
		check_work_time_staff(connectfd ,msg);
		break;
	}



}



int main(int argc, const char *argv[])
{
	
	//初始化TCP
	if(init_TCP(argv[1],argv[2]) < 0)
	{
		exit(0);
	}
	//输入参数校验
	if(argc < 3)
	{
		printf("请输入参数格式：%s <ip> <port>\n",argv[0]);
		exit(-1);
	}
	//打开数据库
	if(sqlite3_open(DATABASE,&db) != SQLITE_OK)
	{
		printf("数据库打开失败！%s\n",sqlite3_errmsg(db));
		exit(-1);
	}
	//初始化数据库
	init_admin();

	doublelist_t=create_doublelist();
	pthread_t tid;
	while(1){
		//处理客户端请求操作
		TCP_MANAGER *tcp_manager = (TCP_MANAGER*)malloc(sizeof(TCP_MANAGER));

		int connectfd;
		printf("wait accept!!\n");	
		socklen_t socklen = sizeof(server_addr);	
		if ((connectfd = accept(socket_TCP_ID,(struct sockaddr *)&(tcp_manager->client_addr), &socklen)) < 0)
		{
			perror("fail to accept");
			exit(-1);
		}
		tcp_manager->connectfd=connectfd;
		get_current_date(tcp_manager->connect_time);	
			
		insert_head_doublelist(doublelist_t,tcp_manager);
		
		if(pthread_create(&tid,NULL,manager_task,tcp_manager) != 0)
		{
			perror("fail to pthread_create!");
			exit(1);
		}
	
	}


	return 0;
}


